#include "Player.h"
#include "world.h"

Player::Player(LPDIRECT3DDEVICE9 device, World *WorldPointer): GameObject(device,50,0,50,0)
{
	WorldPointer_ = WorldPointer;
	ySpeed = 0;
	state = ON_GROUND;
}

Player::~Player(void)
{
}

void Player::Movement(int speed)
{
	Model.nextAnimSet = 1;
	if(speed > 0)
	{
	// check for collision 5 steps infront of characterd	
	x += (cos(Yrot + D3DXToRadian(90)) * speed) * 3;
	z += (sin(Yrot + D3DXToRadian(270)) * speed) * 3;
	UpdateBoundingBoxes();
		if (IfWorldCollide() || IfObjectCollide()) // if there is a collision
		{
			// remove the incremented steps to stop the character
			x -= (cos(Yrot + D3DXToRadian(90)) * speed) * 3;
			z -= (sin(Yrot + D3DXToRadian(270)) * speed) * 3;
			Yrot += 0.075;
			UpdateBoundingBoxes();
		}
		else // elce if there is no collision
		{
			// take of 4 steps to move the player forwards a single step
			x -= (cos(Yrot + D3DXToRadian(90)) * speed)*2;
			z -= (sin(Yrot + D3DXToRadian(270)) * speed)*2;
			UpdateBoundingBoxes();
		}
	}
	else
	{
		Model.nextAnimSet = 0;
	}
}


void Player::Physics()
{
	if(state == IN_AIR)
	{
		ySpeed -= GRAVITY;
		y +=ySpeed;

		if(y <0)
		{
			y = 0;
			ySpeed = 0;
			state = ON_GROUND;
		}
	}
}

void Player::Jump()
{
	if(state == ON_GROUND)
	{
		ySpeed = 3;
		state = IN_AIR;
	}
}

bool Player::IfWorldCollide( )
{
	bool collide = true;

	WorldBBoxCount_ = WorldPointer_ ->numMesh;
	for (int i(0); i < WorldBBoxCount_; ++i)
	{
	collide = true;
	if ((AABoundingBox[1].x < WorldPointer_ ->BoundingBoxes_[i][0].x))
		collide = false;
	if ((AABoundingBox[0].x > WorldPointer_ ->BoundingBoxes_[i][7].x))
		collide = false;

	if ((AABoundingBox[1].z < WorldPointer_ ->BoundingBoxes_[i][0].z))
		collide = false;
	if ((AABoundingBox[0].z > WorldPointer_ ->BoundingBoxes_[i][7].z))
		collide = false;



	if (collide == true)
		break;
	}
	return(collide);
}

bool Player::IfObjectCollide()
{
	bool Chestcollide = false;
	bool NPCcollide = false;

	IfWarpCollide();

	for(int j=0; j < WorldPointer_->Chests.size(); ++j)
	{
		float data[4] = {x,WorldPointer_->Chests[j].x,z,WorldPointer_->Chests[j].z};
		float minX(0),minZ(0),maxX(0),maxZ(0);
		
		Chestcollide = true;

		if( data[0] < data[1])
		{
			minX = data[0];
			maxX = data[1];
		}
		else
		{
			minX = data[1];
			maxX = data[0];
		}


		if(data[2] < data[3])
		{
			minZ = data[2];
			maxZ = data[3];
		}
		else
		{
			minZ = data[3];
			maxZ = data[2];
		}

		float dist = (sqrt(pow((maxX - minX),2)+pow((maxZ - minZ),2)));

		if(dist > WorldPointer_->Chests[j].Radius)
			Chestcollide = false;

		if (Chestcollide == true)
			break;
	}

	for(int j=0; j < WorldPointer_->NPCs.size(); ++j)
	{
		float data[4] = {x,WorldPointer_->NPCs[j].x,z,WorldPointer_->NPCs[j].z};
		float minX(0),minZ(0),maxX(0),maxZ(0);
		
		NPCcollide = true;

		if( data[0] < data[1])
		{
			minX = data[0];
			maxX = data[1];
		}
		else
		{
			minX = data[1];
			maxX = data[0];
		}


		if(data[2] < data[3])
		{
			minZ = data[2];
			maxZ = data[3];
		}
		else
		{
			minZ = data[3];
			maxZ = data[2];
		}

		float dist = (sqrt(pow((maxX - minX),2)+pow((maxZ - minZ),2)));

		if(dist > WorldPointer_->NPCs[j].Radius)
			NPCcollide = false;

		if (NPCcollide == true)
			break;
	}
	return(Chestcollide||NPCcollide);
}


void Player::IfWarpCollide()
{
	bool interact = true;
	int WarpNum(0);
	for(int j=0; j < WorldPointer_->Warps.size(); ++j)
	{
		float data[4] = {x,WorldPointer_->Warps[j].x,z,WorldPointer_->Warps[j].z};
		float minX(0),minZ(0),maxX(0),maxZ(0);

		interact = true;

		if( data[0] < data[1])
		{
			minX = data[0];
			maxX = data[1];
		}
		else
		{
			minX = data[1];
			maxX = data[0];
		}


		if(data[2] < data[3])
		{
			minZ = data[2];
			maxZ = data[3];
		}
		else
		{
			minZ = data[3];
			maxZ = data[2];
		}

		float dist = (sqrt(pow((maxX - minX),2)+pow((maxZ - minZ),2)));

		if(dist > WorldPointer_->Warps[j].interactRadius)
			interact = false;


		if (interact == true)
		{
			WorldPointer_->Warps[WarpNum].Interact();
			break;
		}
	}
}
void Player::Interact()
{
	bool interact = true;
	for(int j=0; j < WorldPointer_->Chests.size(); ++j)
	{
		float data[4] = {x,WorldPointer_->Chests[j].x,z,WorldPointer_->Chests[j].z};
		float minX(0),minZ(0),maxX(0),maxZ(0);

		interact = true;

		if( data[0] < data[1])
		{
			minX = data[0];
			maxX = data[1];
		}
		else
		{
			minX = data[1];
			maxX = data[0];
		}


		if(data[2] < data[3])
		{
			minZ = data[2];
			maxZ = data[3];
		}
		else
		{
			minZ = data[3];
			maxZ = data[2];
		}

		float dist = (sqrt(pow((maxX - minX),2)+pow((maxZ - minZ),2)));

		if(dist > WorldPointer_->Chests[j].interactRadius)
			interact = false;


		if (interact == true){
			WorldPointer_->Chests[j].interact();
			break;
		}
	}

	interact = true;
	int NPCNum(0);
	for(int j=0; j < WorldPointer_->NPCs.size(); ++j)
	{
		float data[4] = {x,WorldPointer_->NPCs[j].x,z,WorldPointer_->NPCs[j].z};
		float minX(0),minZ(0),maxX(0),maxZ(0);

		interact = true;

		if( data[0] < data[1])
		{
			minX = data[0];
			maxX = data[1];
		}
		else
		{
			minX = data[1];
			maxX = data[0];
		}


		if(data[2] < data[3])
		{
			minZ = data[2];
			maxZ = data[3];
		}
		else
		{
			minZ = data[3];
			maxZ = data[2];
		}

		float dist = (sqrt(pow((maxX - minX),2)+pow((maxZ - minZ),2)));

		if(dist > WorldPointer_->NPCs[j].interactRadius)
			interact = false;


		if (interact == true){
			WorldPointer_->NPCs[j].Interact();
			break;
		}
	}	
}

